package com.itaming.lycheeframework.support.utils;

import com.itaming.lycheeframework.common.constant.FrameworkConstant;
import lombok.experimental.UtilityClass;

import java.nio.charset.Charset;
import java.util.Base64;

/**
 * Base64工具类
 *
 * @author A.Ming
 */
@UtilityClass
public class Base64Util {

    /**
     * 编码
     *
     * <p>
     * 默认使用 UTF-8 字符集，自定义字符集请使用 {@link #encode(String, Charset)}
     *
     * @param str 字符串
     * @return 编码后的数据
     */
    public static byte[] encode(String str) {
        return encode(str, FrameworkConstant.DEFAULT_CHARSET);
    }

    /**
     * 编码
     *
     * @param str     字符串
     * @param charset 字符集
     * @return 编码后的数据
     */
    public static byte[] encode(String str, Charset charset) {
        return encode(StringUtil.getBytes(str, charset));
    }

    /**
     * 编码
     *
     * @param bytes 数据
     * @return 编码后的数据
     */
    public static byte[] encode(byte[] bytes) {
        return bytes == null ? null : Base64.getEncoder().encode(bytes);
    }

    /**
     * 编码
     *
     * <p>
     * 默认使用 UTF-8 字符集，自定义字符集请使用 {@link #encodeToString(String, Charset)}
     *
     * @param str 字符串
     * @return 编码后的字符串
     */
    public static String encodeToString(String str) {
        return encodeToString(str, FrameworkConstant.DEFAULT_CHARSET);
    }

    /**
     * 编码
     *
     * @param str     字符串
     * @param charset 字符集
     * @return 编码后的字符串
     */
    public static String encodeToString(String str, Charset charset) {
        return encodeToString(StringUtil.getBytes(str, charset), charset);
    }

    /**
     * 编码
     *
     * <p>
     * 默认使用 UTF-8 字符集，自定义字符集请使用 {@link #encodeToString(byte[], Charset)}
     *
     * @param bytes 数据
     * @return 编码后的字符串
     */
    public static String encodeToString(byte[] bytes) {
        return encodeToString(bytes, FrameworkConstant.DEFAULT_CHARSET);
    }

    /**
     * 编码
     *
     * @param bytes   数据
     * @param charset 字符集
     * @return 编码后的字符串
     */
    public static String encodeToString(byte[] bytes, Charset charset) {
        return StringUtil.newString(encode(bytes), charset);
    }

    /**
     * URL安全编码
     *
     * <p>
     * 默认使用 UTF-8 字符集，自定义字符集请使用 {@link #encodeUrlSafe(String, Charset)}
     *
     * @param str 字符串
     * @return 编码后的数据
     */
    public static byte[] encodeUrlSafe(String str) {
        return encodeUrlSafe(str, FrameworkConstant.DEFAULT_CHARSET);
    }

    /**
     * URL安全编码
     *
     * @param str     字符串
     * @param charset 字符集
     * @return 编码后的数据
     */
    public static byte[] encodeUrlSafe(String str, Charset charset) {
        return encodeUrlSafe(StringUtil.getBytes(str, charset));
    }

    /**
     * URL安全编码
     *
     * @param bytes 数据
     * @return 编码后的数据
     */
    public static byte[] encodeUrlSafe(byte[] bytes) {
        return bytes == null ? null : Base64.getUrlEncoder().encode(bytes);
    }

    /**
     * URL安全编码
     *
     * <p>
     * 默认使用 UTF-8 字符集，自定义字符集请使用 {@link #encodeUrlSafeToString(String, Charset)}
     *
     * @param str 字符串
     * @return 编码后的字符串
     */
    public static String encodeUrlSafeToString(String str) {
        return encodeUrlSafeToString(str, FrameworkConstant.DEFAULT_CHARSET);
    }

    /**
     * URL安全编码
     *
     * @param str     字符串
     * @param charset 字符集
     * @return 编码后的字符串
     */
    public static String encodeUrlSafeToString(String str, Charset charset) {
        return encodeUrlSafeToString(StringUtil.getBytes(str, charset), charset);
    }

    /**
     * URL安全编码
     *
     * <p>
     * 默认使用 UTF-8 字符集，自定义字符集请使用 {@link #encodeUrlSafeToString(byte[], Charset)}
     *
     * @param bytes 数据
     * @return 编码后的字符串
     */
    public static String encodeUrlSafeToString(byte[] bytes) {
        return encodeUrlSafeToString(bytes, FrameworkConstant.DEFAULT_CHARSET);
    }

    /**
     * URL安全编码
     *
     * @param bytes   数据
     * @param charset 字符集
     * @return 编码后的字符串
     */
    public static String encodeUrlSafeToString(byte[] bytes, Charset charset) {
        return StringUtil.newString(encodeUrlSafe(bytes), charset);
    }

    /**
     * 编码
     *
     * <p>
     * 默认使用 UTF-8 字符集，自定义字符集请使用 {@link #decode(String, Charset)}
     *
     * @param str 字符串
     * @return 编码后的数据
     */
    public static byte[] decode(String str) {
        return decode(str, FrameworkConstant.DEFAULT_CHARSET);
    }

    /**
     * 编码
     *
     * @param str     字符串
     * @param charset 字符集
     * @return 编码后的数据
     */
    public static byte[] decode(String str, Charset charset) {
        return decode(StringUtil.getBytes(str, charset));
    }

    /**
     * 编码
     *
     * @param bytes 数据
     * @return 编码后的数据
     */
    public static byte[] decode(byte[] bytes) {
        return bytes == null ? null : Base64.getDecoder().decode(bytes);
    }

    /**
     * 解码
     *
     * <p>
     * 默认使用 UTF-8 字符集，自定义字符集请使用 {@link #decodeToString(String, Charset)}
     *
     * @param str 字符串
     * @return 解码后的字符串
     */
    public static String decodeToString(String str) {
        return decodeToString(str, FrameworkConstant.DEFAULT_CHARSET);
    }

    /**
     * 解码
     *
     * @param str     字符串
     * @param charset 字符集
     * @return 解码后的字符串
     */
    public static String decodeToString(String str, Charset charset) {
        return decodeToString(StringUtil.getBytes(str, charset), charset);
    }

    /**
     * 解码
     *
     * <p>
     * 默认使用 UTF-8 字符集，自定义字符集请使用 {@link #decodeToString(byte[], Charset)}
     *
     * @param bytes 数据
     * @return 解码后的字符串
     */
    public static String decodeToString(byte[] bytes) {
        return decodeToString(bytes, FrameworkConstant.DEFAULT_CHARSET);
    }

    /**
     * 解码
     *
     * @param bytes   数据
     * @param charset 字符集
     * @return 解码后的字符串
     */
    public static String decodeToString(byte[] bytes, Charset charset) {
        return StringUtil.newString(decode(bytes), charset);
    }

    /**
     * URL安全解码
     *
     * <p>
     * 默认使用 UTF-8 字符集，自定义字符集请使用 {@link #decodeUrlSafe(String, Charset)}
     *
     * @param str 字符串
     * @return 解码后的数据
     */
    public static byte[] decodeUrlSafe(String str) {
        return decodeUrlSafe(str, FrameworkConstant.DEFAULT_CHARSET);
    }

    /**
     * URL安全解码
     *
     * @param str     字符串
     * @param charset 字符集
     * @return 解码后的数据
     */
    public static byte[] decodeUrlSafe(String str, Charset charset) {
        return decodeUrlSafe(StringUtil.getBytes(str, charset));
    }

    /**
     * URL安全解码
     *
     * @param bytes 数据
     * @return 解码后的数据
     */
    public static byte[] decodeUrlSafe(byte[] bytes) {
        return bytes == null ? null : Base64.getUrlDecoder().decode(bytes);
    }

    /**
     * URL安全解码
     *
     * <p>
     * 默认使用 UTF-8 字符集，自定义字符集请使用 {@link #decodeUrlSafeToString(String, Charset)}
     *
     * @param str 字符串
     * @return 解码后的字符串
     */
    public static String decodeUrlSafeToString(String str) {
        return decodeUrlSafeToString(str, FrameworkConstant.DEFAULT_CHARSET);
    }

    /**
     * URL安全解码
     *
     * @param str     字符串
     * @param charset 字符集
     * @return 解码后的字符串
     */
    public static String decodeUrlSafeToString(String str, Charset charset) {
        return decodeUrlSafeToString(StringUtil.getBytes(str, charset), charset);
    }

    /**
     * URL安全解码
     *
     * <p>
     * 默认使用 UTF-8 字符集，自定义字符集请使用 {@link #decodeUrlSafeToString(byte[], Charset)}
     *
     * @param bytes 数据
     * @return 解码后的字符串
     */
    public static String decodeUrlSafeToString(byte[] bytes) {
        return decodeUrlSafeToString(bytes, FrameworkConstant.DEFAULT_CHARSET);
    }

    /**
     * URL安全解码
     *
     * @param bytes   数据
     * @param charset 字符集
     * @return 解码后的字符串
     */
    public static String decodeUrlSafeToString(byte[] bytes, Charset charset) {
        return StringUtil.newString(decodeUrlSafe(bytes), charset);
    }

}
